﻿#ifndef _CGUIEVENT_H_
#define _CGUIEVENT_H_ 1


#include "kernel/ref_ptr.h"
#include "kernel/Referenced.h"
#include <vector>

namespace FD
{
	namespace Kernel
	{
		namespace GUI
		{
			enum GUITouchPhase
			{
				TOUCH_UNKNOWN = 0,
				TOUCH_BEGAN = 1,
				TOUCH_MOVED = 2,
				TOUCH_STATIONERY = 3,
				TOUCH_ENDED = 4
			};

			class FD_Kernel_Export TouchPoint:public FD::Kernel::CReferenced
			{
			public:
				/// <summary>
				/// 构造函数
				/// </summary>
				/// <returns></returns>
				TouchPoint();
			public:
				/// <summary>
				/// 构造函数
				/// </summary>
				/// <param name="in_id">触摸点的ＩＤ</param>
				/// <param name="in_phase">触摸点的类型</param>
				/// <param name="in_x">触摸点的X坐标</param>
				/// <param name="in_y">触摸点的Ｙ坐标</param>
				/// <param name="in_tap_count">总点数</param>
				/// <returns></returns>
				TouchPoint(UINT32 in_id,FD::Kernel::GUI::GUITouchPhase in_phase,float in_x,float in_y,UINT32 in_tap_count);
				/// <summary>
				/// 挎贝构造函数
				/// </summary>
				/// <returns></returns>
				TouchPoint(const TouchPoint& rhs);

			public:
				UINT32 mid;
				FD::Kernel::GUI::GUITouchPhase mphase;
				float x;
				float y;
				UINT32 mtapCount;
			};

			typedef std::vector<FD::Kernel::GUI::TouchPoint> TouchPointSet;
			
			class FD_Kernel_Export TouchData:public FD::Kernel::CReferenced
			{
			public:
				//typedef vector<FD::Kernel::GUI::TouchPoint> FD::Kernel::GUI::TouchPointSet;
				typedef TouchPointSet::iterator iterator;
				typedef TouchPointSet::const_iterator const_iterator;
				/// <summary>
				/// 构造函数
				/// </summary>
				/// <returns></returns>
				TouchData();

				TouchData(const TouchData& rhs);

			public:

				TouchData::iterator begin();

				TouchData::const_iterator begin() const;

				TouchData::iterator end();

				TouchData::const_iterator end() const;

				const FD::Kernel::GUI::TouchPoint get(UINT32 i) const;

				UINT32 getNumTouchPoints() const;

			public:
				friend class GUIEvent;
				/// <summary>
				/// 增加触摸点
				/// </summary>
				/// <param name="id">触摸点的ＩＤ</param>
				/// <param name="phase">触摸点的类型</param>
				/// <param name="x">触摸点的X坐标</param>
				/// <param name="y">触摸点的Ｙ坐标</param>
				/// <param name="tap_count">总点数</param>
				/// <returns></returns>
				void addTouchPoint(UINT32 id,FD::Kernel::GUI::GUITouchPhase phase,float x,float y,UINT32 tap_count);

				FD::Kernel::GUI::TouchPointSet mtouchSet;
			};

			class FD_Kernel_Export GUIEvent : public FD::Kernel::CReferenced
			{
			public:
				enum GUIMouseButtonMask
				{
					BUTTON_UnKnown = 0,
					LEFT_MOUSE_BUTTON=1,
					MIDDLE_MOUSE_BUTTON=2,
					RIGHT_MOUSE_BUTTON=4
				};

				enum GUIEventType
				{
					NONE = 0,
					MOUSEDOWN = 1,
					MOUSEUP = 2,
					MOUSEDOUBLECLIK = 4,
					MOUSEMOVE = 8,
					KEYDOWN = 16,
					KEYUP = 32,
					MOUSEWHEEL = 64,
					TOUCHBEGIN = 128,
					TOUCHMOVE = 256,
					TOUCHEND = 512,
					FRAME = 1024,
					CLOSE_WINDOW = 2048,
					QUIT_APPLICATION = 4096,
					WINDOW_RESIZE = 8192,
					USER = 16384
				};

				enum GUIKeySymbol
				{
					KEY_UnKnown = 0,
					
					KEY_0 = 48,
					KEY_1 = 49,
					KEY_2 = 50,
					KEY_3 = 51,
					KEY_4 = 52,
					KEY_5 = 53,
					KEY_6 = 54,
					KEY_7 = 55,
					KEY_8 = 56,
					KEY_9 = 57,

					KEY_A = 65,
					KEY_B = 66,
					KEY_C = 67,
					KEY_D = 68,
					KEY_E = 69,
					KEY_F = 70,
					KEY_G = 71,
					KEY_H = 72,
					KEY_I = 73,
					KEY_J = 74,
					KEY_K = 75,
					KEY_L = 76,
					KEY_M = 77,
					KEY_N = 78,
					KEY_O = 79,
					KEY_P = 80,
					KEY_Q = 81,
					KEY_R = 82,
					KEY_S = 83,
					KEY_T = 84,
					KEY_U = 85,
					KEY_V = 86,
					KEY_W = 87,
					KEY_X = 88,
					KEY_Y = 89,
					KEY_Z = 90,

					KEY_a = 97,
					KEY_b = 98,
					KEY_c = 99,
					KEY_d = 100,
					KEY_e = 101,
					KEY_f = 102,
					KEY_g = 103,
					KEY_h = 104,
					KEY_i = 105,
					KEY_j = 106,
					KEY_k = 107,
					KEY_l = 108,
					KEY_m = 109,
					KEY_n = 110,
					KEY_o = 111,
					KEY_p = 112,
					KEY_q = 113,
					KEY_r = 114,
					KEY_s = 115,
					KEY_t = 116,
					KEY_u = 117,
					KEY_v = 118,
					KEY_w = 119,
					KEY_x = 120,
					KEY_y = 121,
					KEY_z = 122,

					KEY_Backspace = 8,
					KEY_Tab = 9,
					//KEY_Clear = 12,
					KEY_Enter = 13,
					KEY_Shift_L = 16,
					KEY_Shift_R = 21,
					KEY_Ctrl_L = 17,
					KEY_Ctrl_R = 22,
					KEY_Alt_L = 18,
					KEY_Alt_R = 23,
					KEY_Caps_Lock = 20,

					KEY_Escape = 27,
					KEY_Space = 32,
					KEY_Page_Up = 33,
					KEY_Page_Down = 34,
					KEY_End = 35,	
					KEY_Home = 36,
					KEY_Left = 37,
					KEY_Up = 38,
					KEY_Right = 39,
					KEY_Down = 40,	
					KEY_Insert = 45,
					KEY_Delete = 46,

					KEY_F1 = 112,
					KEY_F2 = 113,
					KEY_F3 = 114,
					KEY_F4 = 115,
					KEY_F5 = 116,
					KEY_F6 = 117,
					KEY_F7 = 118,
					KEY_F8 = 119,
					KEY_F9 = 120,
					KEY_F10 = 121,
					KEY_F11 = 122,
					KEY_F12 = 123,

					KEY_Num_Lock = 144,	
					
				};

				enum GUIModKeyMask
				{
					MODKEY_LEFT_SHIFT = 1,
					MODKEY_RIGHT_SHIFT = 2,
					MODKEY_LEFT_CTRL = 4,
					MODKEY_RIGHT_CTRL = 8,
					MODKEY_LEFT_ALT = 16,
					MODKEY_RIGHT_ALT = 32,
					MODKEY_NUM_LOCK = 4096,
					MODKEY_CAPS_LOCK = 8192,
					MODKEY_CTRL = (MODKEY_LEFT_CTRL|MODKEY_RIGHT_CTRL),
					MODKEY_SHIFT = (MODKEY_LEFT_SHIFT|MODKEY_RIGHT_SHIFT),
					MODKEY_ALT = (MODKEY_RIGHT_ALT|MODKEY_RIGHT_ALT)
				};

			public:
				/// <summary>
				/// 构造函数
				/// </summary>
				/// <returns></returns>
				GUIEvent();
			public:
				/// <summary>
				/// 挎贝构造函数
				/// </summary>
				/// <returns></returns>
				GUIEvent(const GUIEvent& rhs);
				/// <summary>
				/// 析构函数
				/// </summary>
				/// <returns></returns>
				virtual ~GUIEvent();
				/// <summary>
				/// 返回累计的事件
				/// </summary>
				/// <returns></returns>
				static FD::Kernel::GUI::GUIEvent* getAccumulatedEventState();
				/// <summary>
				/// 设置事件对象的有没有被处理过
				/// </summary>
				/// <param name="handled">是否被处理过</param>
				/// <returns></returns>
				void setHandled(bool handled)
				{
					mhandled=handled;
				}
				/// <summary>
				/// 获取事件对象有没有被处理过
				/// </summary>
				/// <returns></returns>
				bool getHandled()
				{
					return mhandled;
				}
				/// <summary>
				/// 设置事件对象的类型
				/// </summary>
				/// <param name="eventType">事件的类型</param>
				/// <returns></returns>
				void setEventType(FD::Kernel::GUI::GUIEvent::GUIEventType eventType)
				{
					meventType = eventType;
				}
				/// <summary>
				/// 获取事件对象的类型
				/// </summary>
				/// <returns></returns>
				FD::Kernel::GUI::GUIEvent::GUIEventType getEventType()
				{
					return meventType;
				}
				/// <summary>
				/// 设置事件对象产生时的时间
				/// </summary>
				/// <param name="time">时间</param>
				/// <returns></returns>
				void setTime(double time)
				{
					mtime=time;
				}
				/// <summary>
				/// 获取事件对象的时间
				/// </summary>
				/// <returns></returns>
				double getTime()
				{
					return mtime;
				}
				/// <summary>
				/// 设置事件对象的窗口范围
				/// </summary>
				/// <param name="x">左上角的Ｘ坐标</param>
				/// <param name="y">左上角的Ｙ坐标</param>
				/// <param name="width">宽度</param>
				/// <param name="height">高度</param>
				/// <returns></returns>
				void setWindowRectangle(INT32 x,INT32 y,INT32 width,INT32 height);
				/// <summary>
				/// 获取窗口的Ｘ坐标
				/// </summary>
				/// <returns></returns>
				INT32 getWindowX()
				{
					return mwindowX;
				}
				/// <summary>
				/// 获取窗口的Y坐标
				/// </summary>
				/// <returns></returns>
				INT32 getWindowY()
				{
					return mwindowY;
				}
				/// <summary>
				/// 获取窗口的宽度
				/// </summary>
				/// <returns></returns>
				INT32 getWindowWidth()
				{
					return mwindowWidth;
				}
				/// <summary>
				/// 获取窗口的高度
				/// </summary>
				/// <returns></returns>
				INT32 getWindowHeight()
				{
					return mwindowHeight;
				}
				/// <summary>
				/// 设置事件对象的按键值
				/// </summary>
				/// <param name="key">键盘按键值，值为GUIKeySymbol枚举中的一个</param>
				/// <returns></returns>
				void setKey(GUIKeySymbol key)
				{
					mkey = key;
				}
				/// <summary>
				/// 获取事件对象的按键值
				/// </summary>
				/// <returns>值为GUIKeySymbol枚举中的一个</returns>
				GUIKeySymbol getKey()
				{
					return mkey;
				}
				/// <summary>
				/// 设置事件对象的虚拟按键值
				/// </summary>
				/// <param name="key">键盘按键值，值为GUIKeySymbol枚举中的一个</param>
				/// <returns></returns>
				void setVirtualKey(GUIKeySymbol key)
				{
					mvirtualKey = key;
				}
				/// <summary>
				/// 获取事件对象的虚拟按键值
				/// </summary>
				/// <returns>值为GUIKeySymbol枚举中的一个</returns>
				GUIKeySymbol getVirtualKey()
				{
					return mvirtualKey;
				}
				/// <summary>
				/// 设置事件对象的鼠标键值
				/// </summary>
				/// <param name="button">鼠标键值，为GUIMouseButtonMask枚举中的一个值</param>
				void setButton(GUIMouseButtonMask button)
				{
					mbutton = button;
				}
				/// <summary>
				/// 获取事件对象的鼠标键值
				/// </summary>
				/// <returns>值为GUIMouseButtonMask枚举中的一个值</returns>
				GUIMouseButtonMask getButton()
				{
					return mbutton;
				}
				/// <summary>
				/// 设置事件对象的Ｘ坐标值
				/// </summary>
				/// <param name="x">鼠标的Ｘ坐标</param>
				/// <returns></returns>
				void setX(INT32 x)
				{
					mX = x;
				}
				/// <summary>
				/// 获取事件对象的X坐标
				/// </summary>
				/// <returns></returns>
				INT32 getX()
				{
					return mX;
				}
				/// <summary>
				/// 设置事件对象的Y坐标值
				/// </summary>
				/// <param name="y">鼠标的Y坐标</param>
				/// <returns></returns>
				void setY(INT32 y)
				{
					mY = y;
				}
				/// <summary>
				/// 获取事件对象的Y坐标
				/// </summary>
				/// <returns></returns>
				INT32 getY()
				{
					return mY;
				}
				/// <summary>
				/// 设置事件对象的鼠标掩码
				/// </summary>
				/// <param name="mask">鼠标的键值，值为GUIMouseButtonMask枚举的组合</param>
				/// <returns></returns>
				void setButtonMask(INT32 mask)
				{
					mbuttonMask = mask;
				}
				/// <summary>
				/// 获取事件对象的鼠标掩码，值为GUIMouseButtonMask枚举的组合
				/// </summary>
				/// <returns></returns>
				INT32 getButtonMask()
				{
					return mbuttonMask;
				}
				/// <summary>
				/// 设置事件对象的辅助键的掩码
				/// </summary>
				/// <param name="mask">辅助按键的值，为GUIModKeyMask枚举中的一个值</param>
				/// <returns></returns>
				void setModKeyMask(INT32 mask)
				{
					mmodKeyMask = mask;
				}
				/// <summary>
				/// 获取事件对象的辅助键的掩码
				/// </summary>
				/// <returns>为GUIModKeyMask枚举中的一个值</returns>
				INT32 getModKeyMask()
				{
					return mmodKeyMask;
				}
				/// <summary>
				/// 设置事件对象的滚轮的值
				/// </summary>
				/// <param name="delta">鼠标滚轮的变化值,鼠标向后滚动，值为负，向前液，值为正。delta一般为120的倍数</param>
				/// <returns></returns>
				void setMouseWheelDelta(float delta)
				{
					mmouseWheelDelta = delta;
				}
				/// <summary>
				/// 获取事件对象的滚轮的值
				/// </summary>
				/// <returns></returns>
				float getMouseWheelDelta()
				{
					return mmouseWheelDelta;
				}

				/// <summary>
				/// 添加触摸点
				/// </summary>
				/// <param name="id">触摸点的ＩＤ</param>
				/// <param name="phase">触摸点的类型</param>
				/// <param name="x">触摸点的X坐标</param>
				/// <param name="y">触摸点的Ｙ坐标</param>
				/// <returns></returns>
				void addTouchPoint(UINT32 id,FD::Kernel::GUI::GUITouchPhase phase,float x, float y)
				{
					addTouchPoint(id,phase,x,y,0);
				}

				/// <summary>
				/// 添加触摸点
				/// </summary>
				/// <param name="id">触摸点的ＩＤ</param>
				/// <param name="phase">触摸点的类型</param>
				/// <param name="x">触摸点的X坐标</param>
				/// <param name="y">触摸点的Ｙ坐标</param>
				/// <param name="tapCount">触摸点的数量</param>
				/// <returns></returns>
				void addTouchPoint(UINT32 id,FD::Kernel::GUI::GUITouchPhase phase,float x, float y,UINT32 tapCount);

				/// <summary>
				/// 返回触摸事件的详细信息。
				/// </summary>
				/// <returns></returns>
				FD::Kernel::GUI::TouchData getTouchData()
				{
					return mtouchData;
				}

				/// <summary>
				/// 是否为多点触摸事件
				/// </summary>
				/// <returns></returns>
				bool isMultiTouchEvent()
				{
					return mtouchData.getNumTouchPoints()>0;
				}

				//					/// <summary>
				//					/// 获取事件对象的自定义数据
				//					/// </summary>
				//					/// <returns></returns>
				// 					FD::GraphicEngine::CUserObjectBindings& getUserObjectBindings();
				//					/// <summary>
				//					/// 设置事件对象的自定义事件对象
				//					/// </summary>
				//					/// <returns></returns>
				// 					const FD::GraphicEngine::CUserObjectBindings &getUserObjectBindings() const;
				//
				//public:
				//					/// <summary>
				//					///设置事件对象的自定义数据
				//					/// </summary>
				//					/// <param name="anything">自定义数据</param>
				//					/// <returns></returns>
				//					void setUserAny( const CAny &anything );
				//					/// <summary>
				//					///获取事件对象的自定义数据
				//					/// </summary>
				//					/// <returns></returns>
				//					const CAny &getUserAny() const;

			protected:
				FD::Kernel::GUI::GUIEvent& operator =(const FD::Kernel::GUI::GUIEvent& rhs)
				{
					return *this;
				}

			public:

				mutable bool mhandled; 
				FD::Kernel::GUI::GUIEvent::GUIEventType meventType;
				double mtime;
				GUIKeySymbol mkey;
				GUIKeySymbol mvirtualKey;
				GUIMouseButtonMask mbutton;
				INT32 mbuttonMask;
				INT32 mmodKeyMask;
				INT32 mX;
				INT32 mY;
				INT32 mwindowX;
				INT32 mwindowY;
				INT32 mwindowWidth;
				INT32 mwindowHeight;
				float mmouseWheelDelta;
				FD::Kernel::GUI::TouchData mtouchData;
			};

			typedef FD_Kernel_Export FD::Kernel::ref_ptr<FD::Kernel::GUI::GUIEvent> GUIEventPtr;

			/*class FD_Kernel_Export GUIEventPtr : public FD::Kernel::CReferenced, public FD::Kernel::ref_ptr<FD::Kernel::GUI::GUIEvent>
			{
			public:
				explicit GUIEventPtr(GUIEvent *rep) : FD::Kernel::ref_ptr<GUIEvent>(rep) {}
			public:
				/// <summary>
				/// 构造函数
				/// </summary>
				/// <returns></returns>
				GUIEventPtr();
				/// <summary>
				/// 构造函数
				/// </summary>
				/// <param name="rep">事件对象</param>
				/// <returns></returns>
				//explicit GUIEventPtr(GUIEvent *rep);
				/// <summary>
				/// 挎贝构造函数
				/// </summary>
				/// <param name="tp">待挎贝的对象</param>
				/// <returns></returns>
				GUIEventPtr(const GUIEventPtr &tp);

				/// <summary>
				/// 返回事件对象
				/// </summary>
				/// <returns></returns>
				FD::Kernel::GUI::GUIEvent *get() const
				{
					return FD::Kernel::ref_ptr<FD::Kernel::GUI::GUIEvent>::get();
				}
				/// <summary>
				/// 赋值运算符
				/// </summary>
				/// <param name="tp">的对象</param>
				/// <returns></returns>
				FD::Kernel::GUI::GUIEventPtr &operator = (const FD::Kernel::GUI::GUIEventPtr &r);
				/// <summary>
				/// 赋值运算符
				/// </summary>
				/// <param name="rep">事件对象</param>
				/// <returns></returns>
				FD::Kernel::GUI::GUIEventPtr &operator = (GUIEvent* ref_rep);
			};*/
		}
	}
}

#endif
